package com.whitecat.voting.web;

import com.whitecat.voting.common.Resp;
import com.whitecat.voting.constant.RespCode;
import com.whitecat.voting.constant.SysConstant;
import com.whitecat.voting.dto.MaterialDTO;
import com.whitecat.voting.dto.WorkParam;
import com.whitecat.voting.entity.Candidate;
import com.whitecat.voting.exception.BusinessException;
import com.whitecat.voting.service.CandidateService;
import com.whitecat.voting.service.MaterialService;
import com.whitecat.voting.util.ShiroUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Api(value = "素材接口", tags = {"素材接口"})
@Slf4j
@RestController
@RequestMapping("/material/")
public class MaterialController extends BaseController {

    private final MaterialService materialService;
    private final CandidateService candidateService;

    public MaterialController(MaterialService materialService, CandidateService candidateService) {
        this.materialService = materialService;
        this.candidateService = candidateService;
    }

    @ApiOperation(value = "素材列表", notes = "展示素材列表。")
    @GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
    public Resp<List<MaterialDTO>> list() {
        return ok(materialService.listAll());
    }

    @ApiOperation(value = "排行榜", notes = "展示排行榜前十名。")
    @GetMapping(value = "/ranking", produces = MediaType.APPLICATION_JSON_VALUE)
    public Resp<List<MaterialDTO>> listTop10() {
        return ok(materialService.listAll().stream()
                .filter(item -> item.getVotesCount() > 0)
                .sorted(Comparator.comparing(MaterialDTO::getVotesCount).reversed())
                .limit(10)
                .collect(Collectors.toList()));
    }

    @ApiOperation(value = "报名参赛", notes = "用户报名参赛操作，需先调用上传作品接口。")
    @PostMapping(value = "/signUp", produces = MediaType.APPLICATION_JSON_VALUE)
    public Resp<?> signUp(@RequestBody WorkParam work) {
        String openId = ShiroUtils.getSignInUser().getOpenId();
        String video = materialService.getVideo(openId);
        if (video != null) {
            return fail(RespCode.NOT_FOUND);
        }

        Candidate entity = new Candidate();
        entity.setOpenId(openId);
        entity.setName(work.getName());
        entity.setIntroduction(work.getIntroduction());
        entity.setRegion(work.getRegion().getCode());
        return candidateService.saveOrModify(entity) ? ok() : fail();
    }

    @ApiOperation(value = "上传视频", notes = "用户上传视频操作，需先调用登录接口。")
    @PostMapping(value = "/video", produces = MediaType.APPLICATION_JSON_VALUE)
    public Resp<?> uploadVideo(@RequestPart MultipartFile file) {
        String openId = ShiroUtils.getSignInUser().getOpenId();
        File userMaterialDir = FileUtils.getFile(System.getProperty("user.dir"), SysConstant.DEFAULT_MATERIAL_DIR, openId);
        File videoFile = FileUtils.getFile(userMaterialDir, openId + ".mp4");
        try {
            FileUtils.writeByteArrayToFile(videoFile, file.getBytes(), false);
        } catch (IOException e) {
            throw new BusinessException("Occurring an exception during video uploading!", e);
        }

        materialService.generateScreenshot(videoFile);
        return ok();
    }

    @ApiOperation(value = "我的作品", notes = "查询我的参赛作品。")
    @PostMapping(value = "/myWork", produces = MediaType.APPLICATION_JSON_VALUE)
    public Resp<MaterialDTO> queryMyWork() {
        String openId = ShiroUtils.getSignInUser().getOpenId();
        return ok(materialService.findByOpenId(openId));
    }
}